package com.nwpu.bigdata.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.nwpu.bigdata.dao.EsLogDao;
import com.nwpu.bigdata.dao.mapper.*;
import com.nwpu.bigdata.model.*;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.nwpu.bigdata.dto.BackendResult;
import com.nwpu.bigdata.service.DiagnosisService;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author carlin
 * @date 2018/8/4 0004 11:34
 */
@Service
public class DiagnosisServiceImpl implements DiagnosisService {

    /**
     * logger
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(DiagnosisServiceImpl.class);

    private final FaultReasonMapper faultReasonMapper;

    private final FaultMapper faultMapper;

    private final EsLogDao esLogDao;

    private final HostMapper hostMapper;

    private final MetricMapper metricMapper;

    private final CheckFuncMapper checkFuncMapper;

    @Autowired
    public DiagnosisServiceImpl(FaultReasonMapper faultReasonMapper,
                                FaultMapper faultMapper, EsLogDao esLogDao, HostMapper hostMapper, MetricMapper metricMapper, CheckFuncMapper checkFuncMapper) {
        this.faultReasonMapper = faultReasonMapper;
        this.faultMapper = faultMapper;
        this.esLogDao = esLogDao;
        this.hostMapper = hostMapper;
        this.metricMapper = metricMapper;
        this.checkFuncMapper = checkFuncMapper;
    }

    /**
     * 设置故障原因
     *
     * @param faultId 对应的故障
     * @param reason
     * @return 是否设置成功
     */
    @Override
    public BackendResult<Boolean> setFaultReason(Long faultId, String reason) {
        Fault fault = faultMapper.selectByPrimaryKey(faultId);
        FaultReason faultReason = new FaultReason();
        faultReason.setFaultReason(reason);
        faultReason.setFaultId(faultId);
        faultReason.setRuleId(fault.getRuleId());
        int faultNum = faultReasonMapper.insert(faultReason);
        if (faultNum > 0) {
            return new BackendResult<>(true, true);
        } else {
            return new BackendResult<>(false, "set fault reason error, please check the id!");
        }
    }

    /**
     * 获取故障原因
     *
     * @param user
     * @param faultId 对应的故障
     * @return 故障原因详情
     */
    @Override
    public BackendResult<FaultReasonExtend> getFaultReason(User user, Long faultId) {
        FaultReasonExtend faultReasonExtend = faultReasonMapper.selectFaultExtendByFaultId(faultId);

        if (faultReasonExtend != null) {
            FaultExtend faultExtend = faultMapper.selectFaultById(faultId);
            Host host = hostMapper.selectByPrimaryKey(faultExtend.getRule().getHostId());
            faultExtend.getRule().setHost(host);
            Metric metric = metricMapper.selectByPrimaryKey(faultExtend.getRule().getMetricId());
            faultExtend.getRule().setMetric(metric);
            CheckFunc checkFunc = checkFuncMapper.selectByPrimaryKey(faultExtend.getRule().getTriggerFuncId());
            faultExtend.getRule().setCheckFunc(checkFunc);
            faultReasonExtend.setFaultExtend(faultExtend);
            return new BackendResult<>(true, faultReasonExtend);

        } else {
            //用户没有指定故障原因的时候，需要用户输入故障原因，同时给出故障产生的日志信息
            FaultExtend faultExtend = faultMapper.selectFaultById(faultId);
            Host host = hostMapper.selectByPrimaryKey(faultExtend.getRule().getHostId());
            faultExtend.getRule().setHost(host);
            Metric metric = metricMapper.selectByPrimaryKey(faultExtend.getRule().getMetricId());
            faultExtend.getRule().setMetric(metric);
            CheckFunc checkFunc = checkFuncMapper.selectByPrimaryKey(faultExtend.getRule().getTriggerFuncId());
            faultExtend.getRule().setCheckFunc(checkFunc);
            FaultKeyExtend faultKeyExtend = new FaultKeyExtend();
            faultKeyExtend.setUser(user);
            faultKeyExtend.setKeyword("");
            DateTime startTime = new DateTime(faultExtend.getGmtCreate().getTime()
                    - 5 * 60 * 1000);
            DateTime endTime = new DateTime(faultExtend.getGmtCreate().getTime()
                    + 5 * 60 * 1000);
            Map<String, String[]> conditions = new ConcurrentHashMap<>();
            conditions.put("kubernetes.host", new String[]{host.getHostName()});
            List<ExceptLog> exceptLogs = esLogDao.searchLogByUser("logstash-*",
                    "fluentd", conditions, startTime, endTime, faultKeyExtend);
            faultReasonExtend = new FaultReasonExtend();
            faultReasonExtend.setExceptLogs(exceptLogs);
            faultReasonExtend.setFaultExtend(faultExtend);
            BackendResult<FaultReasonExtend> faultReasonExtendBackendResult =
                    new BackendResult<>(false, "put error info");
            faultReasonExtendBackendResult.setData(faultReasonExtend);
            return faultReasonExtendBackendResult;

        }
    }
}
